<template>
  <el-form
    :id="type === 'search' ? 'form' + random : ''"
    :inline="type !== 'rule' ? true : false"
    ref="ruleFormRef"
    :model="model"
    :rules="props.rules"
    @submit="submitForm"
    :label-width="props.labelWidth ? props.labelWidth : ''"
    :style="{ padding: type !== 'rule' ? '16px 16px 0 16px' : '' }"
  >
    <slot></slot>
    <el-form-item
      v-for="item in props.items"
      :key="item.key"
      :label="item.name"
      :prop="item.key"
      :class="item.required ? 'is-required' : ''"
      :label-width="item.labelWidth ? item.labelWidth : ''"
    >
      <template v-if="item.slot">
        <slot :name="item.slotName"></slot>
      </template>
      <el-input
        suffix-icon="xxxx"
        v-else-if="!item.type || item.type === 'input'"
        v-model="model[item.key]"
        type="text"
        :style="{ width: type == 'search-pop' ? '160px' : '' }"
        :placeholder="item.placeholder || '请输入'"
        v-bind="setAttrs(item)"
        :disabled="item.disabled"
      />
      <el-input
        v-model="model[item.key]"
        v-else-if="!item.type || item.type === 'textarea'"
        :autosize="{ minRows: 4, maxRows: 6 }"
        type="textarea"
        v-bind="setAttrs(item)"
        :placeholder="item.placeholder || '请输入'"
      >
      </el-input>
      <div v-else-if="!item.type || item.type === 'select-pop'" style="width: 100%">
        <el-input
          ref="selectPop"
          style="width: 100%"
          v-model="model[item.key]"
          readonly
          class="select-pop"
          v-bind="setAttrs(item)"
          @click="item.handleFn"
          :placeholder="item.placeholder || '请选择'"
        />
        <slot name="select-pop"></slot>
      </div>
      <SelectSite
        v-model:form="model"
        v-else-if="!item.type || item.type === 'selectSite'"
        :getData="item.getData"
        :keys="item.keys"
        :required="item.required"
      ></SelectSite>
      <!--  <el-input-number style="width:100%" v-model="model[item.key]" v-else-if="item.type === 'number'"
        :placeholder="item.placeholder || '请输入'" :controls="false" v-bind="setAttrs(item)" /> -->
      <template v-else-if="item.type === 'number'">
        <el-input-number
          :style="{ width: item.suffix ? '80%' : '100%' }"
          v-model="model[item.key]"
          :placeholder="item.placeholder || '请输入'"
          :controls="false"
          v-bind="setAttrs(item)"
        >
        </el-input-number>
        <span v-if="item.suffix" style="margin-left: 10px">
          {{ item.suffix }}
        </span>
      </template>
      <template v-else-if="!item.type || item.type === 'label'">
        <selectLabel
          v-model:form="model"
          :type="item.tagType"
          :keys="item.key"
        ></selectLabel>
      </template>
      <el-form-item v-else-if="!item.type || item.type === 'switch'" v-model="model[item.key]">
        <el-switch
          v-bind="setAttrs(item)"
          :active-value="item.activeValue"
          :inactive-value="item.inactiveValue"
          v-model="model[item.key]"
        />
      </el-form-item>
      <el-select
        v-else-if="item.type === 'select'"
        clearable
        :style="{ width: type == 'search-pop' ? '160px' : '100%' }"
        v-bind="setAttrs(item)"
        filterable
        v-model="model[item.key]"
        :placeholder="item.placeholder || '请选择'"
      >
        <el-option
          v-for="(option, i) of item.options"
          :key="i"
          :label="option[(item['props'] && item['props']['key']) || 'label']"
          :value="option[(item['props'] && item['props']['value']) || 'value']"
        />
      </el-select>
      <selectPage
        v-else-if="item.type === 'select-page'"
        :item="item"
        v-bind="setAttrs(item)"
        :firstName="model[item.option.name]"
        v-model="model[item.key]"
      />
      <selectPageMultiple
        v-else-if="item.type === 'select-page-multiple'"
        :item="item"
        v-bind="setAttrs(item)"
        v-model="model[item.key]"
      />
      <el-radio-group
        v-else-if="item.type === 'radio'"
        v-model="model[item.key]"
        :placeholder="item.placeholder || '请选择'"
        style="width: 100%"
        v-bind="setAttrs(item)"
      >
        <el-radio
          v-for="(option, i) of item.options"
          :key="i"
          :label="option[(item['props'] && item['props']['key']) || 'value']"
          >{{ option[(item['props'] && item['props']['label']) || 'label'] }}</el-radio
        >
      </el-radio-group>
      <el-date-picker
        v-else-if="item.type === 'date'"
        v-model="model[item.key]"
        type="date"
        v-bind="setAttrs(item)"
        value-format="YYYY-MM-DD"
        :placeholder="item.placeholder || '请选择'"
      />
      <el-date-picker
        style="width: 336px"
        v-else-if="item.type === 'datetimerange'"
        v-model="model[item.key]"
        type="datetimerange"
        :disabled="item.disabled"
        v-bind="setAttrs(item)"
        range-separator="~"
        value-format="YYYY-MM-DD HH:ss:mm"
        start-placeholder="开始时间"
        end-placeholder="结束时间"
        :default-time="[new Date(0, 0, 0, 0, 0, 0), new Date(0, 0, 0, 23, 59, 59)]"
      />
    </el-form-item>
    <slot name="desc"></slot>
    <div class="form-btn" v-if="type === 'rule'">
      <slot name="prefix-button" />
      <el-button @click="cancel"> 取 消 </el-button>
      <el-button type="primary" :loading="loading" native-type="submit"> 确 定 </el-button>
      <slot name="suffix-button" />
    </div>
    <el-form-item v-else>
      <slot name="prefix-button" />
      <el-button type="primary" native-type="submit">
        <el-icon>
          <Search />
        </el-icon>
        查询
      </el-button>
      <el-button @click="resetForm">
        <el-icon>
          <RefreshLeft />
        </el-icon>
        重置
      </el-button>
      <slot name="suffix-button" />
    </el-form-item>
    <slot name="footer"></slot>
  </el-form>
</template>
<script lang="ts" setup>
import { Debounce } from '@/hooks/throttle';
import type { FormInstance } from 'element-plus';
import { useVModel } from '@/hooks/useVModel';
import selectPage from './selectPage.vue';
import selectPageMultiple from './selectPageMultiple.vue';
import store from '@/store';
import selectLabel from './selectLabel.vue'
const props = defineProps({
  form: {
    type: Object,
  },
  type: {
    type: String,
  },
  items: {
    type: Object,
  },

  // rule
  handleOk: {
    type: Function,
  },
  handleCancel: {
    type: Function,
  },
  rules: {
    type: Object,
  },
  labelWidth: {
    type: String,
    default: '100px',
  },
  refresh: {
    type: Function,
  },

  // seaech
  colLayout: {
    type: Object,
    default: {
      xs: 24,
      sm: 12,
      md: 8,
      lg: 7,
      xl: 4,
    },
  },

  // 默认高度
  defaultHeight: {
    type: Number,
    default: 238,
  },
});
const selectPop = ref(null);
const loading = ref(false);
const emit = defineEmits(['update:form', 'search']);
const model = useVModel(props, 'form', emit);
const ruleFormRef = ref<FormInstance>();
const submitForm = (e) => {
  e.preventDefault();
  if (props.type !== 'rule') {
    // 查询
    emit('search', props.form);
  } else {
    ruleFormRef.value.validate((valid, fields) => {
      if (valid) {
        loading.value = true;
        props
          .handleOk(model.value)
          .then((res) => {
            ElMessage({
              message: '保存成功',
              type: 'success',
            });
            loading.value = false;
            props.handleCancel();
            props.refresh();
          })
          .catch(() => {
            loading.value = false;
          });
      } else {
        console.log('error submit!', model.value, fields);
      }
    });
  }
};

const cancel = () => {
  props.handleCancel();
};
const setAttrs = (params) => {
  const { slot, ...options } = params;
  return { ...options, slot };
};

// search
const defaultForm = reactive({
  ...props.form,
});
// 重置表单
const resetForm = () => {
  for (let key in defaultForm) {
    if (Array.isArray(defaultForm[key])) {
      defaultForm[key] = [];
    } else if (typeof defaultForm[key] === 'object') {
      for (let ckey in defaultForm[key]) {
        defaultForm[key][ckey] = null;
      }
    }
  }
  emit('update:form', {
    ...defaultForm,
    // 重置按钮不重置内容管理分类查询
    dictionaryKey: props.form.dictionaryKey || undefined,
    dictionaryId: props.form.dictionaryId || undefined,
    typeId: props.form.typeId || undefined,
  });
  emit('search', null);
};

// defineExpose({ submitForm, cancel })
const formHeight = ref(0);
watch(formHeight, (val) => {
  getTableHeight(val);
});
// 设置表格高度
const getTableHeight = (h) => {
  let height = window.innerHeight - props.defaultHeight - h;
  store.commit('table/SET_TABLEHEIGHT', height);
};
// 监听搜索form  dom元素的高度
// 生成searchform随机id
const random = Math.ceil(Math.random() * 100);
const getContainerkHeight = () => {
  nextTick(() => {
    let dom = document.getElementById('form' + random);
    formHeight.value = dom?.offsetHeight;
  });
};
onMounted(() => {
  if (props.type === 'search') {
    getContainerkHeight();
    window.addEventListener('resize', Debounce(getContainerkHeight, 500));
  }
});
onBeforeUnmount(() => {
  if (props.type === 'search') window.removeEventListener('resize', getContainerkHeight);
});
defineExpose({ selectPop, ruleFormRef, resetForm });
</script>

<style lang="scss" scoped>
.select-pop {
  :deep(.el-input__inner) {
    cursor: pointer;
    outline-color: aliceblue;
  }
}
</style>
